package com.tongtong.middleware.blockchain.controller;

import com.tongtong.middleware.blockchain.client.web3j.WEB3JService;
import com.tongtong.middleware.blockchain.service.ERC721Service;
import com.tongtong.middleware.vo.params.erc721.*;
import com.tongtong.middleware.vo.response.SignTxRes;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import xyz.xtt.common.response.ApiResult;

import java.math.BigInteger;
import java.util.Objects;

@RestController
@RequestMapping("/eth/erc721")
@RefreshScope
@Slf4j
public class ERC721Controller {
	@Autowired
	WEB3JService web3jService;
	@Autowired
	ERC721Service erc721Service;

	/**
	 * 铸造NFT
	 */
	@PostMapping("/mintNFT")
	public ApiResult<String> erc721MintNFT(@Valid @RequestBody MintNFTParams request, BindingResult bindingResult) {
		log.info("【成功】/eth/erc721/mintNFT request:  to=>{} tokenId=>{}",
				request.getTo(), request.getTokenId());

		if (bindingResult.hasErrors()) {
			return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
		}
		SignTxRes res = erc721Service.mintNFT(request.getTo(), request.getTokenId());
		if (!res.getErrMsg().isEmpty()) {
			log.error("【失败】/eth/erc721/mintNFT response: {}", res.getErrMsg());
			return ApiResult.failure(9527, res.getErrMsg());
		} else {
			log.info("【成功】/eth/erc721/mintNFT response: {}", res.getHash());
			return ApiResult.ok(res.getHash());
		}
	}
	/**
	 * 授权角色
	 */
	@PostMapping("/approval")
	public ApiResult<String> approval(@Valid @RequestBody ApprovalParams request, BindingResult bindingResult) {
		log.info("【成功】/eth/erc721/approval request:  account=>{}",
				request.getAccount());
		if (bindingResult.hasErrors()) {
			return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
		}
		SignTxRes res = erc721Service.approval(request.getAccount());
		if (!res.getErrMsg().isEmpty()) {
			log.error("【失败】/eth/erc721/approval response: {}", res.getErrMsg());
			return ApiResult.failure(9527, res.getErrMsg());
		} else {
			log.info("【成功】/eth/erc721/approval response: {}", res.getHash());
			return ApiResult.ok(res.getHash());
		}
	}

	/**
	 * 转移NFT
	 */
	@PostMapping("/transfer")
	public ApiResult<String> erc721Transfer(@Valid @RequestBody TransferParams request, BindingResult bindingResult) {
		log.info("【成功】/eth/erc721/transfer request:  from=>{} to=>{} tokenId=>{}",
				request.getFrom(), request.getTo(), request.getTokenId());
		if (bindingResult.hasErrors()) {
			return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
		}
		SignTxRes res = erc721Service.transfer(request.getFrom(), request.getTo(), request.getTokenId());
		if (!res.getErrMsg().isEmpty()) {
			log.error("【失败】/eth/erc721/transfer response: {}", res.getErrMsg());
			return ApiResult.failure(9527, res.getErrMsg());
		} else {
			log.info("【成功】/eth/erc721/transfer response: {}", res.getHash());
			return ApiResult.ok(res.getHash());
		}
	}

	/**
	 * 销毁NFT
	 */
	@PostMapping("/burnNFT")
	public ApiResult<String> erc721BurnNFT(@Valid @RequestBody BurnNFTParams request, BindingResult bindingResult) {
		log.info("【成功】/eth/erc721/burnNFT request:  tokenId=>{}", request.getTokenId());
		if (bindingResult.hasErrors()) {
			return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
		}
		SignTxRes res = erc721Service.burnNFT(request.getTokenId());
		if (!res.getErrMsg().isEmpty()) {
			log.error("【失败】/eth/erc721/burnNFT response: {}", res.getErrMsg());
			return ApiResult.failure(9527, res.getErrMsg());
		} else {
			log.info("【成功】/eth/erc721/burnNFT response: {}", res.getHash());
			return ApiResult.ok(res.getHash());
		}
	}

	/**
	 * 查询指定用户拥有TokenID的数量
	 */
	@GetMapping("/balanceOf")
	public ApiResult<String> erc721BalanceOf(@RequestParam("account") String account) {
		if (account == null || account.length() != 42) {
			return ApiResult.failure(9527, "account is illegal");
		}
		String res = erc721Service.balanceOf(account);

		return ApiResult.ok(res);
	}

	/**
	 * 查询用户是否被指定操作者授权
	 */
	@GetMapping("/isApprovedForAll")
	public ApiResult<String> erc721IsApprovedForAll(@RequestParam("account") String account, @RequestParam("operator") String operator) {
		if (account == null || account.length() != 42) {
			return ApiResult.failure(9527, "account is illegal");
		}
		if (operator == null || operator.length() != 42) {
			return ApiResult.failure(9527, "operator is illegal");
		}
		String res = erc721Service.isApprovedForAll(account, operator);

		return ApiResult.ok(res);
	}

	/**
	 * 查询指定TokenID的TokenURI
	 */
	@GetMapping("/tokenURI")
	public ApiResult<String> tokenURI(@RequestParam("tokenId") BigInteger tokenId) {
		if (tokenId == null || tokenId.compareTo(BigInteger.ZERO) <= 0) {
			return ApiResult.failure(9527, "tokenId is illegal");
		}
		String res = erc721Service.tokenURI(tokenId);

		return ApiResult.ok(res);
	}

	/**
	 * 查询指定TokenID的拥有者地址
	 */
	@GetMapping("/ownerOf")
	public ApiResult<String> ownerOf(@RequestParam("tokenId") BigInteger tokenId) {
		if (tokenId == null || tokenId.compareTo(BigInteger.ZERO) <= 0) {
			return ApiResult.failure(9527, "tokenId is illegal");
		}
		String res = erc721Service.ownerOf(tokenId);

		return ApiResult.ok(res);
	}
}
